package com.toomoss.USB2XXX;

import java.util.Arrays;
import java.util.List;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;

public interface USB2LIN_EX extends Library {
	USB2LIN_EX INSTANCE  = (USB2LIN_EX) Native.loadLibrary("USB2XXX",USB2LIN_EX.class);
	//定义LIN消息帧结构体
	public class LIN_EX_MSG  extends Structure{
		
	    public static class ByReference extends LIN_EX_MSG implements Structure.ByReference {}  
	    public static class ByValue extends LIN_EX_MSG implements Structure.ByValue {}  
	  
		@Override
		protected List getFieldOrder() {
			// TODO Auto-generated method stub
			return Arrays.asList(new String[]{"Timestamp", "MsgType", "CheckType", "DataLen","Sync","PID","Data","Check","BreakBits","Reserve1"});
		}
	    
		public int  Timestamp;    			//从机接收数据时代表时间戳，单位为0.1ms;主机读写数据时，表示数据读写后的延时时间，单位为ms
	    public byte MsgType;      			//帧类型
	    public byte CheckType;    			//校验类型
	    public byte DataLen;      			//LIN数据段有效数据字节数
	    public byte Sync;         			//固定值，0x55
	    public byte PID;          			//帧ID
	    public byte[] Data = new byte[8];	//数据
	    public byte Check;        			//校验,只有校验数据类型为LIN_EX_CHECK_USER的时候才需要用户传入数据
	    public byte BreakBits;    			//该帧的BRAK信号位数，有效值为10到26，若设置为其他值则默认为13位
	    public byte Reserve1;				//保留字节
	}

	//定义函数返回错误代码
	public static int LIN_EX_SUCCESS           =  (0);   //函数执行成功
	public static int LIN_EX_ERR_NOT_SUPPORT   =  (-1);  //适配器不支持该函数
	public static int LIN_EX_ERR_USB_WRITE_FAIL=  (-2);  //USB写数据失败
	public static int LIN_EX_ERR_USB_READ_FAIL =  (-3);  //USB读数据失败
	public static int LIN_EX_ERR_CMD_FAIL      =  (-4);  //命令执行失败
	public static int LIN_EX_ERR_CH_NO_INIT    =  (-5);  //该通道未初始化
	public static int LIN_EX_ERR_READ_DATA     =  (-6);  //LIN读数据失败
	public static int LIN_EX_ERR_PARAMETER     =  (-7);  //函数参数传入有误
	//校验类型
	public static byte LIN_EX_CHECK_STD    = 0;  //标准校验，不含PID
	public static byte LIN_EX_CHECK_EXT    = 1;  //增强校验，包含PID
	public static byte LIN_EX_CHECK_USER   = 2;  //自定义校验类型，需要用户自己计算并传入Check，不进行自动校验
	public static byte LIN_EX_CHECK_NONE   = 3;  //不计算校验数据
	public static byte LIN_EX_CHECK_ERROR  = 4;  //接收数据校验错误
	//主从机定义
	public static byte LIN_EX_MASTER       = 1;  //主机
	public static byte LIN_EX_SLAVE        = 0;  //从机
	//VBAT引脚电压定义
	public static byte LIN_EX_VBAT_0V     = 0;	//VBAT输出0V
	public static byte LIN_EX_VBAT_12V    = 1;	//VBAT输出12V
	public static byte LIN_EX_VBAT_5V     = 2;	//VBAT输出5V
	//帧类型
	public static byte LIN_EX_MSG_TYPE_UN  = 0;  //未知类型
	public static byte LIN_EX_MSG_TYPE_MW  = 1;  //主机向从机发送数据
	public static byte LIN_EX_MSG_TYPE_MR  = 2;  //主机从从机读取数据
	public static byte LIN_EX_MSG_TYPE_SW  = 3;  //从机发送数据
	public static byte LIN_EX_MSG_TYPE_SR  = 4;  //从机接收数据
	public static byte LIN_EX_MSG_TYPE_BK  = 5;  //只发送BREAK信号，若是反馈回来的数据，表明只检测到BREAK信号
	public static byte LIN_EX_MSG_TYPE_SY  = 6;  //表明检测到了BREAK，SYNC信号
	public static byte LIN_EX_MSG_TYPE_ID  = 7;  //表明检测到了BREAK，SYNC，PID信号
	public static byte LIN_EX_MSG_TYPE_DT  = 8;  //表明检测到了BREAK，SYNC，PID,DATA信号
	public static byte LIN_EX_MSG_TYPE_CK  = 9;  //表明检测到了BREAK，SYNC，PID,DATA,CHECK信号
	//VBAT输出电压配置
	public static byte VBAT_0V    = 0;//VBAT输出0V
	public static byte VBAT_12V   = 1;//VBAT输出12V
	public static byte VBAT_5V    = 2;//VBAT输出5V
	/**
	 * @brief  LIN总线初始化，在使用LIN相关函数之前必须先调用该函数
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param  BaudRate LIN总线波特率值，单位为bps，最小值为2000，最大值为100000
	 * @param  MasterMode LIN工作模式，0-从机，1-主机
	 * @return 函数执行状态
	 * @retval 0 函数调用成功
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_Init(int DevHandle,byte LINIndex,int BaudRate,byte MasterMode);
	/**
	 * @brief  LIN总线初始化，在使用LIN相关函数之前必须先调用该函数
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param  BaudRateBps LIN总线波特率值，单位为bps，最小值为2000，最大值为100000
	 * @param  MasterMode LIN工作模式，0-从机，1-主机
	 * @param  ByteSpaceUs 主机发送数据时，字节间隔时间，单位为微秒
	 * @param  ResponseSpaceUs 帧头与数据之间的时间间隔，单位为微秒
	 * @param  TimeOutMs 主机读或者从机接收数据时，数据不满8字节时的超时时间，设置为0底层根据波特率自适应
	 * @return 函数执行状态
	 * @retval 0 函数调用成功
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_Init2(int DevHandle, byte LINIndex, int BaudRateBps, byte MasterMode, int ByteSpaceUs, int ResponseSpaceUs, int TimeOutMs);
	/**
	 * @brief  主机模式下，阻塞模式收发LIN数据
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param[in]  pInMsg 输入帧指针
	 * @param[out]  pOutMsg 输出帧指针
	 * @param  MsgLen 输入帧数
	 * @return 函数执行状态
	 * @retval >0 pOutMsg里面存储的有效帧数
	 * @retval =0 数据收发失败
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_MasterSync(int DevHandle,byte LINIndex,LIN_EX_MSG[] pInMsg,LIN_EX_MSG[] pOutMsg, int MsgLen);
	/**
	 * @brief  主机模式发送同步间隔信号，一般用于唤醒总线上睡眠的从设备
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @return 函数执行状态
	 * @retval =0 函数执行成功
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_MasterBreak(int DevHandle,byte LINIndex);
	/**
	 * @brief  主机模式写数据
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param  PID 帧ID
	 * @param[in]  pData 待发送数据缓冲区指针
	 * @param  DataLen 待发送数据有效数据字节数
	 * @param  CheckType 发送数据校验类型，0-标准校验，校验数据不包含ID，1-增强校验，校验数据包含ID
	 * @return 函数执行状态
	 * @retval =0 函数执行成功
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_MasterWrite(int DevHandle,byte LINIndex,byte PID,byte[] pData,byte DataLen,byte CheckType);
	/**
	 * @brief  主机模式读数据
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param  PID 帧ID
	 * @param[out]  pData 读取数据存储缓冲区指针
	 * @return 函数执行状态
	 * @retval >0 成功读取到从机返回数据字节数
	 * @retval =0 没有读到从机返回的数据，有可能是因为从机没有响应数据
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_MasterRead(int DevHandle,byte LINIndex,byte PID,byte[] pData);
	/**
	 * @brief  设置从机ID模式为发送或者接收数据模式
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param[in]  pLINMsg 帧指针，帧里面的MsgType来决定该ID是发送数据还是接收数据
	 * @param  MsgLen 有效帧数
	 * @return 函数执行状态
	 * @retval =0 函数执行成功
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_SlaveSetIDMode(int DevHandle,byte LINIndex,LIN_EX_MSG[] pLINMsg, int MsgLen);
	/**
	 * @brief  读取从机ID模式帧
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param[out]  pLINMsg 存储从机ID模式帧指针
	 * @return 函数执行状态
	 * @retval >=0 成功读取到的帧数
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_SlaveGetIDMode(int DevHandle,byte LINIndex,LIN_EX_MSG[] pLINMsg);
	/**
	 * @brief  读取从机模式下接收到的帧
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param[out]  pLINMsg 存储帧指针
	 * @return 函数执行状态
	 * @retval >=0 成功读取到的帧数
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_SlaveGetData(int DevHandle,byte LINIndex,LIN_EX_MSG[] pLINMsg);
	/**
	 * @brief  控制VBAT引脚输出指定电压值
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param  VbatValue VBAT输出电压值\n
	 * @ref LIN_EX_VBAT_0V 关闭VBAT引脚电压输出，关闭输出后，VBAT引脚需要外接电压LIN才能正常工作\n
	 * @ref LIN_EX_VBAT_12V VBAT引脚输出12V\n
	 * @ref LIN_EX_VBAT_5V VBAT引脚输出5V
	 * @return 函数执行状态
	 * @retval 0 控制电压成功
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_CtrlPowerOut(int DevHandle,byte LINIndex,byte VbatValue);
	/**
	 * @brief  获取VBAT引脚电压，该函数已经弃用
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param[out]  pBatValue 引脚电压值输出指针
	 * @return 函数执行状态
	 * @retval 0 读取电压值成功
	 * @retval <0 函数调用失败
	 * @attention 该函数已经被弃用，调用该函数无法正确获取到VBAT引脚电压，不建议调用
	 */
	int LIN_EX_GetVbatValue(int DevHandle,short[] pBatValue);
	/**
	 * @brief  主机调度表模式收发数据，使用该模式收发数据可以精确控制帧间隔时间，函数调用也是非阻塞的
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param[in]  pLINMsg 调度表模式收发数据帧指针
	 * @param  MsgLen 有效帧数
	 * @return 函数执行状态
	 * @retval 0 函数调用成功
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_MasterStartSch(int DevHandle,byte LINIndex,LIN_EX_MSG[] pLINMsg,int MsgLen);
	/**
	 * @brief  停止执行调度表
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @return 函数执行状态
	 * @retval 0 函数调用成功
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_MasterStopSch(int DevHandle,byte LINIndex);
	/**
	 * @brief  读取主机模式调度表
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param  pLINMsg 调度表存储指针
	 * @return 函数执行状态
	 * @retval 0 函数调用成功
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_MasterGetSch(int DevHandle,byte LINIndex,LIN_EX_MSG[] pLINMsg);
	/**
	 * @brief  设置调度表运行次数，必须在启动调度表之前调用，否则调度表会根据最后一帧的帧周期决定是发送一次还是循环发送
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param  RunTimes 调度表运行次数，若设置为0xFFFFFFFF则一直发送，直到调用停止运行函数
	 * @return 函数执行状态
	 * @retval 0 函数调用成功
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_MasterSetSchRunTimes(int DevHandle, byte LINIndex, int RunTimes);
	/**
	 * @brief  控制总线输出高电平或者是低电平，注意输出低电平后，无法正常输出LIN数据，需要重新控制输出高电平才能继续输出LIN数据
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  LINIndex LIN通道号，0-LIN1，1-LIN2，2-LIN3，3-LIN4
	 * @param  BusState 总线状态，0-总线输出低电平，1-总线输出高电平
	 * @return 函数执行状态
	 * @retval 0 函数调用成功
	 * @retval <0 函数调用失败
	 */
	int LIN_EX_SetBusState(int DevHandle, byte LINIndex, byte BusState);

	
}
